package com.admin.service;

import com.admin.model.SensitiveWords;
import com.admin.model.ServiceInstance;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.discovery.EurekaClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

@Component
public class NacosServiceManagerImpl implements NacosServiceManager {

    // 注入分组名列表
    @Value("${nacos.group-names}")
    private List<String> defaultGroupNames;

    @Value("${nacos.service-names}")
    private List<String> defaultServiceNames;

    private RestTemplate restTemplate = new RestTemplate();

    private ObjectMapper objectMapper = new ObjectMapper();

    private final NamingService namingService;

    public NacosServiceManagerImpl(@Value("${nacos.server-addr}") String serverAddr) throws NacosException {
        Properties properties = new Properties();
        // 将 Nacos 服务器地址从 Spring 配置中注入
        properties.put("serverAddr", serverAddr);
        // 使用提供的服务器地址创建 Nacos NamingService 实例
        this.namingService = NacosFactory.createNamingService(properties);
    }

    @Override
    public ListView<String> getAllServiceNames() throws NacosException {
        // 使用 Nacos API 获取所有服务的名称列表
        return namingService.getServicesOfServer(1, Integer.MAX_VALUE);
    }

    @Override
    public List<ServiceInfo> getServicesByGroup() throws NacosException {
        List<ServiceInfo> subscribeServices = namingService.getSubscribeServices();
        return subscribeServices.stream()
                .filter(serviceInfo -> defaultGroupNames.contains(serviceInfo.getGroupName()))
                .collect(Collectors.toList());
    }

    @Override
    public List<ServiceInfo> getServicesByNameList() throws NacosException {
        List<ServiceInfo> subscribeServices = namingService.getSubscribeServices();
        return subscribeServices.stream()
                .filter(serviceInfo -> defaultServiceNames.contains(serviceInfo.getName()))
                .collect(Collectors.toList());
    }

    /**
     * 从一组 ServiceInfo 对象中提取所有服务实例的 IP 地址和端口号
     * @param serviceInfos 服务信息对象列表
     * @return 包含 IP 地址和端口号的字符串列表
     */
    @Override
    public List<String> getAllServiceAddresses(List<ServiceInfo> serviceInfos) {
        List<String> allAddresses = new ArrayList<>();
        for (ServiceInfo serviceInfo : serviceInfos) {
            for (Instance instance : serviceInfo.getHosts()) {
                String address = instance.getIp() + ":" + instance.getPort();
                allAddresses.add(address);
            }
        }
        return allAddresses;
    }

    @Override
    public void performActionWithServiceInfo(List<ServiceInfo> serviceInfos, SensitiveWords sensitiveWords) {
        String jsonMessage;
        try {
            jsonMessage = objectMapper.writeValueAsString(sensitiveWords); // 将 SensitiveWords 对象转换为 JSON 字符串
        } catch (Exception e) {
            throw new RuntimeException("Error serializing SensitiveWords object", e);
        }

        for (ServiceInfo serviceInfo : serviceInfos) {
            for (Instance instance : serviceInfo.getHosts()) {
                String serviceAddress = instance.getIp() + ":" + instance.getPort();
                notifyServiceAsync(serviceAddress , sensitiveWords);
            }
        }
    }

    @Async
    public CompletableFuture<Void> notifyServiceAsync(String serviceAddress, SensitiveWords sensitiveWords) {
        try {
            String message = objectMapper.writeValueAsString(sensitiveWords); // 将对象转换为 JSON 字符串
            String url = "http://" + serviceAddress + "/api/notify";
            restTemplate.postForObject(url, message, String.class);
        } catch (Exception e) {
            System.out.println("Failed to notify service at " + serviceAddress + ": " + e.getMessage());
        }
        return CompletableFuture.completedFuture(null);
    }
}

